#ifndef CONFIG_CENTER5_IPC_SHM_20110412
#define CONFIG_CENTER5_IPC_SHM_20110412

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <iostream>
#include <errno.h>

class CIpcShm
{
public:
    CIpcShm();
    ~CIpcShm();

    int32_t Initialize(void* pShm, uint32_t dwKey, int32_t dwFlag, uint32_t dwMaxShmSize, bool& isCreated);
    char* GetShm(uint32_t dwKey, uint32_t dwSize, int32_t dwFlag);
    int32_t Detach();
    int32_t DelShm();
    char* GetLastErrMsg();
    //int         m_iShmId;
private:
    int         m_iShmId;
    void*       m_pShm;
    char        m_szErrMsg[1024];
};

CIpcShm::CIpcShm() : m_iShmId(-1), m_pShm(NULL)
{
    memset(m_szErrMsg, 0, sizeof(m_szErrMsg));
}
CIpcShm::~CIpcShm()
{
}
/*
int32_t CIpcShm::Initialize(void * pShm, uint32_t dwKey, int32_t dwFlag, uint32_t dwMaxShmSize)
{
    pShm = GetShm(dwKey, dwMaxShmSize, dwFlag);
    if (pShm == NULL)
    {
        return -1;
    }
    
    return 0;
}
*/
char* CIpcShm::GetShm(uint32_t dwKey, uint32_t dwSize, int32_t dwFlag)
{
    //void* pShm = NULL;
    
    m_iShmId = shmget(dwKey, dwSize, dwFlag);
    if (m_iShmId < 0)
    {
        snprintf(m_szErrMsg, sizeof(m_szErrMsg), 
                "%s|%d|%s| shmget errno:%d, strerror:%s, Key:0x%x, ShmSiz:%d, Flag:%o",
                __FILE__, __LINE__, __func__, errno, strerror(errno),
                dwKey, dwSize, dwFlag);
        return NULL;
    }

    int32_t dwAcessFlag = SHM_RDONLY;
    if ( (dwFlag & 0222) != 0)
    {
        dwAcessFlag = 0;
    }
    //int32_t dwAcessFlag = 0;

    m_pShm = shmat(m_iShmId, NULL, dwAcessFlag);
    if (m_pShm == (void*)-1)
    {
        snprintf(m_szErrMsg, sizeof(m_szErrMsg), 
                "%s|%d|%s| shmat errno:%d, strerror:%s, Key:0x%x, ShmSiz:%d, Flag:%o, AcessFlag:%o",
                __FILE__, __LINE__, __func__, errno, strerror(errno),
                dwKey, dwSize, dwFlag, dwAcessFlag);
        return NULL;
    }

    return reinterpret_cast<char*>(m_pShm);
}

int32_t CIpcShm::Detach()
{
    if (m_pShm != NULL)
        return shmdt(m_pShm);
    
    return 0;
}

int32_t CIpcShm::DelShm()
{
    return shmctl(m_iShmId, IPC_RMID, NULL);
}

char* CIpcShm::GetLastErrMsg()
{
    return m_szErrMsg;
}

#endif //CONFIG_CENTER5_IPC_SHM_20110412
